#include <REGX52.H>
#include "iic.h"
#include "oledfont.h"
#include "Delay.h"


/**
  * @brief  写地址
  * @param  command 要写的地址
  * @retval 无
  */
void oled_w_command(unsigned char command)
{
	iic_start();
	iic_w(0x78);//设备地址
	iic_r_ack();
	iic_w(0x00);//内存地址
	iic_r_ack();
	iic_w(command);
	iic_r_ack();
	iic_stop();
}

/**
  * @brief  写数据
  * @param  dat 要写的数据
  * @retval 
  */
void oled_w_data(unsigned char dat)
{
	iic_start();
	iic_w(0x78);//设备地址
	iic_r_ack();
	iic_w(0x40);//内存地址
	iic_r_ack();
	iic_w(dat);
	iic_r_ack();
	iic_stop();
}

/**
  * @brief  初始化
  * @retval 无
  */
void oled_init()
{
	oleddelay(500);
	oled_w_command(0xae);//–turn off oled panel 关闭显示
	oled_w_command(0x00);//—set low column address设置起始列的低四位 0x0x
	oled_w_command(0x10);//—set high column address设置起始列的高四位0x1x
	oled_w_command(0x40);//–set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
	oled_w_command(0x81);//–set contrast control register设置对比度
	oled_w_command(0xff); // Set SEG Output Current Brightness对比度为oxff
	oled_w_command(0xa1);//–Set SEG/Column Mapping 0xa0左右反置 0xa1正常
	oled_w_command(0xc8);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
	oled_w_command(0xa6);//–set normal display
	oled_w_command(0xa8);//–set multiplex ratio(1 to 64)
	oled_w_command(0x3f);//–1/64 duty
	oled_w_command(0xd3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
	oled_w_command(0x00);//-not offset
	oled_w_command(0xd5);//–set display clock divide ratio/oscillator frequency
	oled_w_command(0x80);//–set divide ratio, Set Clock as 100 Frames/Sec
	oled_w_command(0xd9);//–set pre-charge period
	oled_w_command(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
	oled_w_command(0xda);//–set com pins hardware configuration
	oled_w_command(0x12);
	oled_w_command(0xdb);//–set vcomh
	oled_w_command(0x40);//Set VCOM Deselect Level
	oled_w_command(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)设置地址模式
	//水平寻址，垂直寻址，页寻址
	oled_w_command(0x02);// 地址模式为页寻址
	oled_w_command(0x8d);//–set Charge Pump enable/disable
	oled_w_command(0x14);//–set(0x10) disable
	oled_w_command(0xa4);// Disable Entire Display On (0xa4/0xa5)
	oled_w_command(0xa6);// Disable Inverse Display On (0xa6/a7)
	oled_w_command(0xaf);//–turn on oled panel开启显示
	oleddelay(100);
}


/**
  * @brief  
  * @param  
  * @retval 
  */
void oled_put_char_16x16(unsigned char x,unsigned char y,unsigned char t)
//设置显示坐标函数,t为0时，字符为8x16t, 为1时，字符为16x16
{
	oled_w_command(0x20);
	oled_w_command(0x00);//设置地址模式为水平选址
	//set page
	oled_w_command(0x22);
	oled_w_command(y);
	oled_w_command(0x01+y);
	//set colum
	oled_w_command(0x21);
	oled_w_command((0x08+0x08*t)*x);
	oled_w_command((0x08+0x08*t)*x+(0x07+0x08*t));
}

/**
  * @brief  清屏函数
  * @retval 无
  */
void oled_clear(void)
{ unsigned char i,j;
	oled_w_command(0x20);
	oled_w_command(0x02);
	for(i=0;i<8;i++)
	{
	 oled_w_command(0xb0+i);
	 oled_w_command(0x00);
	 oled_w_command(0x10);
	 for(j=0;j<128;j++)
	 {
	 oled_w_data(0x00);
	 }
	}
}

/**
  * @brief  坐标设置 
  * @param  x 列  0~128  (若显示12*12则10列5行)
	* @param  y 列  0~64  	(若显示16*16则8列4行)
  * @retval 无
  */
void OLED_Set_Pos(unsigned char x, unsigned char y) 
{ 
	oled_w_command(0xb0+y);
	oled_w_command(((x&0xf0)>>4)|0x10);
	oled_w_command((x&0x0f));
}

/**
  * @brief  在指定地点显示字符
  * @param  x  列 0~128  (若显示12*12则10列5行)
	* @param  y  行	0~64		(若显示16*16则8列4行)
	* @param  chr 显示的字符
	* @param  sizey 字符大小 8为：6X8字号  16：8x16字号
  * @retval 无
  */
void OLED_ShowChar(unsigned char x,unsigned char y,unsigned char chr,unsigned char sizey)
{      	
	unsigned char c=0,sizex=sizey/2;
	unsigned int i=0,size1;
	if(sizey==8)size1=6;
	else size1=(sizey/8+((sizey%8)?1:0))*(sizey/2);
	c=chr-' ';//得到偏移后的值
	OLED_Set_Pos(x,y);
	for(i=0;i<size1;i++)
	{
		if(i%sizex==0&&sizey!=8) OLED_Set_Pos(x,y++);
		if(sizey==8) oled_w_data(asc2_0806[c][i]);//6X8字号
		else if(sizey==16) oled_w_data(asc2_1608[c][i]);//8x16字号
//		else if(sizey==xx) OLED_WR_Byte(asc2_xxxx[c][i],OLED_DATA);//用户添加字号
		else return;
	}
}

/**
  * @brief  在指定地点显示字符串
  * @param  x  列 0~128  (若显示12*12则10列5行)
	* @param  y  行	0~64		(若显示16*16则8列4行)
	* @param  *chr 显示的字符串
	* @param  sizey 字符大小 8为：6X8字号(8行(直接就是1~8)，21个(要乘8))  16：8x16字号
  * @retval 无
  */
void OLED_ShowString(unsigned char x,unsigned char y,unsigned char *chr,unsigned char sizey)
{
	unsigned char j=0;
	while (chr[j]!='\0')
	{		
		OLED_ShowChar(x,y,chr[j++],sizey);
		if(sizey==8)x+=6;
		else x+=sizey/2;
	}
}

/**
  * @brief  计算次方（内部方法）
  * @param  
  * @retval 
  */
unsigned int oled_pow(unsigned char m,unsigned char n)
{
	unsigned int result=1;	 
	while(n--)result*=m;    
	return result;
}



/**
  * @brief  在指定地点显示数字,显示范围0 - 65535
  * @param  x  列 0~128  (若显示12*12则10列5行)
	* @param  y  行	0~64		(若显示16*16则8列4行)
	* @param  num 显示的数字  0 - 65535
	* @param  len 显示的数字长度
	* @param  sizey 字符大小 
  * @retval 无
  */
void OLED_ShowNum(unsigned char x,unsigned char y,unsigned int num,unsigned char len,unsigned char size2)
{         	
	unsigned char t,temp;
	unsigned char enshow=0;						   
	for(t=0;t<len;t++)
	{
		temp=(num/oled_pow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				OLED_ShowChar(x+(size2/2)*t,y,'0',size2);
				continue;
			}else enshow=1; 
		 	 
		}
	 	OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2); 
	}
} 

/**
  * @brief  在指定地点显示中文
  * @param  x  列 0~128  (若显示12*12则10列5行)
	* @param  y  行	0~64		(若显示16*16则8列4行)
	* @param  no 在数字中的索引位置
	* @param  sizey 字符大小 
  * @retval 无
  */
void OLED_ShowChinese(unsigned char x,unsigned char y,unsigned char no,unsigned char sizey)
{
	unsigned int i,size1=(sizey/8+((sizey%8)?1:0))*sizey;
	for(i=0;i<size1;i++)
	{
		if(i%sizey==0) OLED_Set_Pos(x,y++);
		if(sizey==16) oled_w_data(Hzk[no][i]);//16x16字号
    else if(sizey==12) oled_w_data(Hzk1[no][i]);//12X12字号
		//else if(sizey==12) oled_w_data(Hzk1[no][i]);//用户添加字号   记得换字模组		
		else return;
	}				
}

/**
  * @brief  显示图片
  * @param  x  列 0~128  (若显示12*12则10列5行)
	* @param  y  行	0~64		(若显示16*16则8列4行) 
	* @param  sizex  图片大小(占列)
	* @param  sizey  图片大小(占行)
	* @param  BMP[]  取模的数组
  * @retval  无
  */
void OLED_DrawBMP(unsigned char x,unsigned char y,unsigned char sizex, unsigned char sizey,unsigned char BMP[])
{ 	
  unsigned int j=0;
	unsigned char i,m;
	sizey=sizey/8+((sizey%8)?1:0);
	for(i=0;i<sizey;i++)
	{
		OLED_Set_Pos(x,i+y);
    for(m=0;m<sizex;m++)
		{      
			oled_w_data(BMP[j++]);	    	
		}
	}
} 








